@SysLog 日志注解使用

日志注解功能

@SysLog 注解用于记录系统操作日志,通过 AOP 切面拦截方法调用,异步记录操作信息,避免影响业务性能。

POM 依赖

在需要使用日志功能的模块中添加以下依赖:

<!--日志处理-->
<dependency>
	<groupId>com.pig4cloud</groupId>
	<artifactId>pig-common-log</artifactId>
	<version>${log.version}</version>
</dependency>

基本使用

在 Controller 接口方法上使用 @SysLog 注解,描述当前操作的作用:

@SysLog("添加终端")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_client_add')")
public R add(@Valid @RequestBody SysOauthClientDetails sysOauthClientDetails) {
	return new R<>(sysOauthClientDetailsService.save(sysOauthClientDetails));
}

进阶用法

动态日志标题

使用 expression 属性支持 SpEL 表达式,实现动态日志标题:

@SysLog(expression = "'添加角色'.concat(#sysRole.roleName)")
@PostMapping
public R addRole(@Valid @RequestBody SysRole sysRole) {
	// 业务逻辑
}
@SysLog(expression = "#sysRole.roleName.concat('角色操作')")
@PutMapping
public R updateRole(@Valid @RequestBody SysRole sysRole) {
	// 业务逻辑
}
SpEL 表达式支持

expression 属性支持 Spring Expression Language(SpEL),可以访问方法参数、拼接字符串等,实现灵活的日志标题生成。

实现原理

AOP 切面处理

通过 AOP 切面拦截带有 @SysLog 注解的方法,获取注解值并异步发送事件,减少日志操作对业务性能的影响:

@Aspect
@Slf4j
public class SysLogAspect {

	@Around("@annotation(sysLog)")
	public Object around(ProceedingJoinPoint point, SysLog sysLog) throws Throwable {
		String strClassName = point.getTarget().getClass().getName();
		String strMethodName = point.getSignature().getName();
		log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
		SpringContextHolder.publishEvent(new SysLogEvent(logVo));
		return obj;
	}

}

事件监听处理

监听器接收到日志事件后,通过 Feign 调用远程服务进行日志存储:

@Slf4j
@AllArgsConstructor
public class SysLogListener {
	private final RemoteLogService remoteLogService;

	@Async
	@Order
	@EventListener(SysLogEvent.class)
	public void saveSysLog(SysLogEvent event) {
		SysLog sysLog = (SysLog) event.getSource();
		remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
	}
}
异步处理优势

使用 @Async 注解实现异步日志记录,避免阻塞主业务流程,提升系统响应性能。

异步配置说明

日志记录使用 Spring 的异步方法执行功能,需要在启动类或配置类上添加 @EnableAsync 注解启用异步支持。

更多详细信息请参考 Spring Framework API 文档